iT邦幫忙

2

Puppeteer - 爬蟲初學

Ares 2019-05-29 15:58:579832 瀏覽
  • 分享至 

  • xImage
  •  

使用介紹

先進行安裝,詳細可參考 puppeteer

$ npm i puppeteer

接下來看一下範例

// 引入 puppeteer
const puppeteer = require('puppeteer');

(async () => {
  // 設定 puppeteer 參數
  const browser = await puppeteer.launch({
    // 是否在背景運行瀏覽器
    headless: false,
  });
  // 開啟瀏覽器
  const page = await browser.newPage();
  // 前往網站
  await page.goto('https://example.com');
  // 截圖並儲存到 test 資料夾,檔名為 img.png (要先新增資料夾)
  await page.screenshot({path: './test/img.png'});
  // 關閉瀏覽器
  await browser.close();
})();

可以看到 puppeteer 的指令都是很語意化的,很容易就能上手,再來我們看一下參數

launch 常用參數

launch 可使用的參數很多,在此介紹幾個比較常用的,其餘可參考文件

  1. headless < boolean >
    是否在背景運行瀏覽器,預設為 true
  2. userDataDir < string >
    會在設定的資料夾內產生用戶數據,紀錄登入狀態好用!
  3. slowMo < number >
    設定每一步的延遲毫秒數
  4. args < Array < string > >
    傳遞給瀏覽器的參數
  5. timeout < number >
    等待瀏覽器啟動的最長時間(毫秒),預設為 30 秒
    ※這只是瀏覽器啟動的時間,不包括其他步驟執行等待的時間
  6. devtools < Boolean >
    啟動時是否打開開發者工具,若開啟此選項,headless 必須為 true

常用功能介紹

設定瀏覽器參數

const browser = await puppeteer.launch({
  headless: false,
  slowMo: 100
});

瀏覽器開關

// 開啟瀏覽器
const page = await browser.newPage();
// 前往 url
await page.goto('https://www.google.com/');
// 關閉瀏覽器
await browser.close();

轉跳頁面等待

// 等待選擇器
await page.waitForSelector('#hello');
//等待 function,可傳入參數或變數
const selector = '.foo';
await page.waitForFunction(selector => !!document.querySelector(selector), {}, selector);
// 等待 1 秒,亦可傳入 function 或 選擇器,為上面兩個的縮寫
await page.waitFor(1000);
await page.waitFor('#hello');
await page.waitFor(() => !!document.querySelector('.foo'));
// 等待頁面轉跳完成
await page.waitForNavigation();

※ waitForNavigation 建議搭配 Promise.all 一起使用,否則容易跳出超時錯誤

await Promise.all([
  page.reload(),
  page.waitForNavigation()
]);

使用者操作

// 在 input 輸入內容
await page.type('#hello', 'hi');
// 點擊按鈕
await page.click('#button');
// 選擇單選或多選內容
await page.select('#select', '1');
// focus 一個選擇器
await page.focus('#hello');
// hover 一個選擇器
await page.hover('#hello');
// 執行一段 JS 程式
await page.evaluate(() => alert('hello'));
// 上一頁
await page.goBack();
// 下一頁
await page.goForward();
// 重新整理頁面
await page.reload();

鍵盤

// 按著 Shift
await page.keyboard.down('Shift');
// 按一下 A
await page.keyboard.press('KeyA');
// 放開 Shift
await page.keyboard.up('Shift');

滑鼠

// 移動滑鼠
await page.mouse.move(0, 0);
// 按著滑鼠
await page.mouse.down();
// 放開滑鼠
await page.mouse.up();

選擇器

將選擇器宣告為變數要在其上下文使用,否則會跳錯

// 在該頁面執行 document.querySelector,沒有則為 null
const hello = await page.$('.hello');
// 在該頁面執行 document.querySelectorAll,沒有則為 null
const hi = await page.$$('.hi');
// 在該頁面執行 document.querySelector,將其作為第一個參數傳入
const searchValue = await page.$eval('#search', el => el.value);
// 在該頁面執行 Array.from(document.querySelectorAll(selector)),將其作為第一個參數傳入
const divsCounts = await page.$$eval('div', divs => divs.length);

監聽事件

監聽對話框事件觸發時執行 function,可參考文件

async function event(){
  // 打印彈跳視窗訊息
  console.log(dialog.message());
  // 將文字輸入 prompt 對話框,或是直接確定彈跳視窗框
  await dialog.accept([promptText]);
  // 取消彈跳視窗
  await dialog.dismiss();
}
// 監聽事件
await page.on('dialog', event);
// 移除監聽事件
await page.removeListener('dialog', event);

設定頁面參數

// 改變以下方法的預設默認等待時間
// page.goto(url, options)
// page.goBack(options)
// page.goForward(options)
// page.reload(options)
// page.waitForNavigation(options)
await page.setDefaultNavigationTimeout(30000);
// 設定 Cookie
await page.setCookie(cookieObject1, cookieObject2);
// 設定 userAgent
await page.setUserAgent(userAgent);
// 設定為離線模式
await page.setOfflineMode(true);

獲取資料

// 回傳頁面的 pdf
await page.pdf();
// 螢幕截圖
await page.screenshot({path: './test/img.png'});
// 獲取此頁的 cookies
page.cookies([...urls]);

小功能

瀏覽器視窗最大化

const browser = await puppeteer.launch({
  // 瀏覽器最大化
  args: ['--start-maximized']
});
let currentScreen = await page.evaluate(() => {
  return {
    // 回傳視窗寬度與高度
    width: window.screen.availWidth,
    height: window.screen.availHeight
  };
});
// 將頁面設定寬高
await page.setViewport(currentScreen);

阻擋 request

將特定的 request 阻擋,可參考文件

await page.setRequestInterception(true);
page.on('request', (request) => {
    // 如果請求類型是 document 則正常請求,其餘則阻擋
    if (request.resourceType === 'document') {
        request.continue();
    } else {
        request.abort();
    }
});

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言